home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
newsgrp
/
group98c.txt
/
000146_icon-group-sender _Thu Dec 17 16:33:02 1998.msg
< prev
next >
Wrap
Internet Message Format
|
2000-09-20
|
4KB
Return-Path: <icon-group-sender>
Received: (from root@localhost)
by baskerville.CS.Arizona.EDU (8.9.1a/8.9.1) id QAA26376
for icon-group-addresses; Thu, 17 Dec 1998 16:32:56 -0700 (MST)
Message-Id: <199812172332.QAA26376@baskerville.CS.Arizona.EDU>
From: "Nevin Liber" <nevin@eviloverlord.com>
To: <icon-group@optima.CS.Arizona.EDU>
Subject: digisort
Date: Thu, 17 Dec 1998 17:18:15 -0600
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
Importance: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3155.0
Errors-To: icon-group-errors@optima.CS.Arizona.EDU
Status: RO
Ken Walker <mailto:kenneth.walker@sfo.harbinger.com> wrote:
> Here is a rather straightforward solution to the problem of
> sorting digits while preserving the sign of an integer.
Since ASCII "-" comes before "0" in sort order, there is no need to special
case the minus sign. Here is a smaller straightforward (IMHO) solution,
which is the same in principle as Ken's, yet differs very widely in the
details:
procedure digisort(i)
local L
local s
L := list()
every put(L, !i)
s := ""
every s ||:= !sort(L)
return integer(s)
end
1. I tend to use the idiom L := list() instead of L := [].
2. Ken used string scanning to build the list, while I used element
generation.
3. Ken used the destructive (to a list L1) get(L1) to build the string,
while I used the non-destructive element generation !L1.
> I thought of trying csets, but they discard duplicate digits...
digisort() really consists of two subproblems: counting and sorting. If
you seperate out the counting, you can use cset() to do the sorting, as in:
procedure digisort(i)
local T
local s
T := table("")
every s := !i do T[s] ||:= s
s := ""
every s ||:= T[!cset(i)]
return integer(s)
end
T is a table with each digit as a key whose value is a string of that digit
with a length corresponding to the number of times that digit appears in i,
and cset(i) does the sorting.
If you wanted to make the counting more explicit, you could do something
like:
procedure digisort(i)
local T
local s1
local s2
T := table(0)
every T[!i] +:= 1
s1 := ""
every s2 := !cset(i) do s1||:= repl(s2, T[s2])
return integer(s1)
end
If you didn't want to build up a list or a table, you could do the sorting
first and then the counting by multiple passes over (the string of) i, as
in:
procedure digisort(i)
local s
local s1
local s2
s := string(i)
s2 := ""
every s1 := !cset(s) do s ? {
while tab(find(s1)) do {
s2 ||:= move(1)
}
}
return integer(s2)
end
> There should be a solution that is shorter and more obscure;
Here you go :-):
procedure digisort(i)
local s
s := ""
every s ||:= (i ? (tab(find(!cset(&subject))) & move(1)))
return integer(s)
end
You can even replace
cset(&subject)
with
cset(i)
to make it ever-so-slightly shorter, but I think that taking the cset of a
string is ever-so-slightly faster than taking the cset of an integer. Of
course, one could find parallels between the internal way that cset(s)
converts a string to a cset (I'm guessing by a bucket sort) and the
digisort() algorithm itself...
> (You can tell I've been programming too much in C by all the
> semicolons at the end of lines; it also took me a few tries
> to get all the colons before the equals. :-)
(And I've been programming too much in MUMPS lately, which is why all my
variables are only one or two letters long. :-))
__
Nevin ":-)" Liber <mailto:nliber@nationalsystems.com> (312) 855-1000 x199
National Systems Corporation
414 North Orleans Street, Suite 501
Chicago, IL 60610-4490
fax: (312) 222-1605
<http://www.nationalsystems.com>